package com.janko.springbootbase.juc;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * 字面意思回环栅栏，通过它可以实现让一组线程等待至某个状态之后再全部同时执行。
 * 叫做回环是因为当所有等待线程都被释放以后，CyclicBarrier可以被重用。
 * 叫做栅栏，大概是描述所有线程被栅栏挡住了，当都达到时，一起跳过栅栏执行，也算形象。我们可以把这个状态就叫做barrier。
 */
public class C0_CyclicBarrier_Test {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier=new CyclicBarrier(3,new C1_CyclicTourGuideTask());
        Executor executor = Executors.newFixedThreadPool(3);
        executor.execute(new C2_CyclicTravelTask(cyclicBarrier,"A Star",5));
        executor.execute(new C2_CyclicTravelTask(cyclicBarrier,"B Boss",3));
        executor.execute(new C2_CyclicTravelTask(cyclicBarrier,"C Common Humen",1));

//          demoCyclic();
//        jisuangongzi();
    }

    public static  void jisuangongzi(){
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
            @Override
            public void run() {
                System.out.println("分别计算出员工1和员工2的工资了");
            }
        });
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("计算出员工1的工资");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        }, "thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("计算出员工2的工资");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        }, "thread2");
        thread1.start();
        thread2.start();
        System.out.println("====end【主线程未被阻塞】====");
    }

    private static void demoCyclic() {
        /**
         * 可以尝试用在批量更新的是地方
         */
        CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {
            @Override
            public void run() {
                // 例如开始执行批量更新，或者拼接SQL的地方
                System.out.println("is 5,go");
            }
        });


        for(int i=0; i<100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        barrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }

}

